﻿using ServiceOperater.Helpers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace ServiceOperater.ViewModels
{
    /// <summary>
    /// Xml Operate : http://www.cnblogs.com/txw1958/archive/2013/01/16/csharp-xml.html
    /// </summary>
    static class ServiceFileOperater
    {
        // 返回所创建的完整路径名
        public static String CreateEmptyFolder(FileTreeNodeViewModel parentFtnVm)
        {
            String fullPath = System.IO.Path.Combine((parentFtnVm == null ? ConfigHelper.ServiceFolderPath : parentFtnVm.FullPath), "新建文件夹");

            System.IO.Directory.CreateDirectory(fullPath);
            return fullPath;
        }

        // 返回所创建的完整路径名
        public static String CreateEmptyFile(FileTreeNodeViewModel parentFtnVm)
        {
            String fullPath = Path.Combine((parentFtnVm == null ? ConfigHelper.ServiceFolderPath : parentFtnVm.FullPath), "新建文件.xml");

            // --- http://www.cnblogs.com/txw1958/archive/2013/01/16/csharp-xml.html
            XmlDocument xmldoc = new XmlDocument();
            //加入XML的声明段落,<?xml version="1.0" encoding="UTF-8"?>
            XmlDeclaration xmldecl;
            xmldecl = xmldoc.CreateXmlDeclaration("1.0", "UTF-8", null);
            xmldoc.AppendChild(xmldecl);

            //加入一个根元素
            XmlElement xmlRootElement = xmldoc.CreateElement("", "service-config", "");
            xmldoc.AppendChild(xmlRootElement);

            //保存创建好的XML文档
            xmldoc.Save(fullPath);

            return fullPath;
        }


        // 没有保存service实体的操作; 只有保存action去判断service不存在才去保存进文件
        public static void SaveActionNode(ActionTreeNodeViewModel actionRecord, String filePath)
        {
            var serviceRecord = actionRecord.Parent;

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

            //查找<service-config>
            XmlNode root = xmlDoc.SelectSingleNode("/service-config");

            // 确保service节点存在
            XmlElement specialServiceNode = (XmlElement)xmlDoc.SelectSingleNode(String.Format("/service-config/service[@id='{0}']", serviceRecord.OriginId));
            if (null == specialServiceNode)
            {
                //创建一个<service>节点 
                specialServiceNode = xmlDoc.CreateElement("service");
                //设置该节点id属性 
                specialServiceNode.SetAttribute("id", serviceRecord.Id);
                root.AppendChild(specialServiceNode);
            }

            // 确保action节点存在
            XmlElement specialActionNode = (XmlElement)specialServiceNode.SelectSingleNode(String.Format("action[@name='{0}']", actionRecord.OriginName));

            if (null == specialActionNode)
            {
                //创建一个<action>节点 
                specialActionNode = xmlDoc.CreateElement("action");
                specialServiceNode.AppendChild(specialActionNode);
            }
            else
            {
                // 移除所有的子节点
                specialActionNode.RemoveAll();
            }

            specialActionNode.SetAttribute("name", actionRecord.Name);
            //------ must


            XmlElement propertyNode = xmlDoc.CreateElement("property");
            propertyNode.SetAttribute("name", "sqlId");
            propertyNode.SetAttribute("value", actionRecord.SqlId);
            specialActionNode.AppendChild(propertyNode);

            propertyNode = xmlDoc.CreateElement("property");
            propertyNode.SetAttribute("name", "sqlType");
            propertyNode.SetAttribute("value", actionRecord.SqlType);
            specialActionNode.AppendChild(propertyNode);

            propertyNode = xmlDoc.CreateElement("property");
            propertyNode.SetAttribute("name", "result");
            propertyNode.SetAttribute("value", actionRecord.Result);
            specialActionNode.AppendChild(propertyNode);

            //------ conditional
            if (!String.IsNullOrWhiteSpace(actionRecord.ResultType))
            {
                propertyNode = xmlDoc.CreateElement("property");
                propertyNode.SetAttribute("name", "resultType");
                propertyNode.SetAttribute("value", actionRecord.ResultType);
                specialActionNode.AppendChild(propertyNode);
            }

            if (!String.IsNullOrWhiteSpace(actionRecord.Parameter))
            {
                propertyNode = xmlDoc.CreateElement("property");
                propertyNode.SetAttribute("name", "parameter");
                propertyNode.SetAttribute("value", actionRecord.Parameter);
                specialActionNode.AppendChild(propertyNode);
            }

            if (null != actionRecord.IsPage)
            {
                propertyNode = xmlDoc.CreateElement("property");
                propertyNode.SetAttribute("name", "isPage");
                propertyNode.SetAttribute("value", actionRecord.IsPage.ToString().ToLowerInvariant());
                specialActionNode.AppendChild(propertyNode);
            }

            if (!String.IsNullOrWhiteSpace(actionRecord.Handler))
            {
                propertyNode = xmlDoc.CreateElement("property");
                propertyNode.SetAttribute("name", "handler");
                propertyNode.SetAttribute("value", actionRecord.Handler);
                specialActionNode.AppendChild(propertyNode);
            }

            if (!String.IsNullOrWhiteSpace(actionRecord.Condition))
            {
                propertyNode = xmlDoc.CreateElement("property");
                propertyNode.SetAttribute("name", "condition");
                propertyNode.SetAttribute("value", actionRecord.Condition);
                specialActionNode.AppendChild(propertyNode);
            }

            if (!String.IsNullOrWhiteSpace(actionRecord.Ref))
            {
                propertyNode = xmlDoc.CreateElement("property");
                propertyNode.SetAttribute("name", "refenerce");
                propertyNode.SetAttribute("value", actionRecord.Ref);
                specialActionNode.AppendChild(propertyNode);
            }

            xmlDoc.Save(filePath);

            // 将action,service标识为实体
            actionRecord.IsVirtual = false;
            serviceRecord.IsVirtual = false;
            actionRecord.IsInEditMode = false;
            serviceRecord.IsInEditMode = false;
        }

        public static void ModifyServiceName(ServiceTreeNodeViewModel serviceRecord)
        {
            String filePath = serviceRecord.LocationFile.FullPath;

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

            //查找<service>
            XmlElement specialServiceNode = (XmlElement)xmlDoc.SelectSingleNode(String.Format("/service-config/service[@id='{0}']", serviceRecord.OriginId));

            if (serviceRecord == null)
            {
                throw new ArgumentException("can not found service [ " + serviceRecord.OriginId + " ]");
            }

            specialServiceNode.SetAttribute("id", serviceRecord.Id);
            xmlDoc.Save(filePath);
        }

        public static void ModifyActionName(ActionTreeNodeViewModel actionRecord)
        {
            var serviceRecord = actionRecord.Parent;
            String filePath = serviceRecord.LocationFile.FullPath;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

            //查找<service>
            XmlElement specialServiceNode = (XmlElement)xmlDoc.SelectSingleNode(String.Format("/service-config/service[@id='{0}']", serviceRecord.OriginId));

            if (specialServiceNode == null)
            {
                throw new ArgumentException("can not found service [ " + serviceRecord.OriginId + " ]");
            }

            XmlElement specialActionNode = (XmlElement)specialServiceNode.SelectSingleNode(String.Format("action[@name='{0}']", actionRecord.OriginName));
            if (specialActionNode == null)
            {
                throw new ArgumentException("can not found action [ " + actionRecord.OriginName + " ]");
            }

            specialActionNode.SetAttribute("name", actionRecord.Name);
            xmlDoc.Save(filePath);
        }

        public static bool RemoveServiceNode(ServiceTreeNodeViewModel serviceRecord)
        {
            String filePath = serviceRecord.LocationFile.FullPath;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

            //查找<service-config>
            XmlNode root = xmlDoc.SelectSingleNode("/service-config");

            //XmlElement specialServiceNode = (XmlElement)xmlDoc.SelectSingleNode(String.Format("/service-config/service[@id='{0}']", serviceRecord.OriginId));
            //if (null == specialServiceNode)
            //{
            //    return;
            //}
            bool isRemovedSuccess = false;
            var serviceNodeList = root.ChildNodes;
            for (int i = 0; i < serviceNodeList.Count; i++)
            {
                var xmlNode = serviceNodeList.Item(i);
                if (xmlNode is XmlComment)
                {
                    continue;
                }
                XmlElement xe = (XmlElement)serviceNodeList.Item(i);
                if (xe.GetAttribute("id") == serviceRecord.OriginId)
                {
                    root.RemoveChild(xe);
                    isRemovedSuccess = true;
                    break;
                    //if (i < serviceNodeList.Count)
                    //{
                    //    i = i - 1;
                    //}
                }
            }

            xmlDoc.Save(filePath);
            return isRemovedSuccess;


        }

        public static bool RemoveActionNode(ActionTreeNodeViewModel actionRecord)
        {
            var serviceRecord = actionRecord.Parent;
            String filePath = serviceRecord.LocationFile.FullPath;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

            XmlElement specialServiceNode = (XmlElement)xmlDoc.SelectSingleNode(String.Format("/service-config/service[@id='{0}']", serviceRecord.OriginId));
            if (null == specialServiceNode)
            {
                return false;
            }

            bool isRemovedSuccess = false;
            var actionNodeList = specialServiceNode.ChildNodes;
            for (int i = 0; i < actionNodeList.Count; i++)
            {
                var xmlNode = actionNodeList.Item(i);
                if (xmlNode is XmlComment)
                {
                    continue;
                }
                XmlElement xe = (XmlElement)actionNodeList.Item(i);
                if (xe.GetAttribute("name") == actionRecord.OriginName)
                {
                    specialServiceNode.RemoveChild(xe);
                    isRemovedSuccess = true;
                    break;
                }
            }

            xmlDoc.Save(filePath);
            return isRemovedSuccess;
        }
    }
}
